//Copyright (c) 2010 Jimmy Merari

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

var Cinovasi = {};
var C = Cinovasi;
$j = jQuery;

C.clearField = function(container)
{
    var getType = function (el)
    {
        var t = el.type;
        switch( t )
        {
            case "select": case "select-one": case "select-multiple":t = "select";    break;
            case "text": case "textarea": case "password": case "hidden": t = "text"; break;
            case "checkbox": case "radio": t = t;                                     break;
        }
        return t;
    };

    var ctl = $j(container).find('[name]');

    for(var i = 0; i < ctl.length; i++)
    {
        var el = ctl[i];
        var n = el.name;
        var elid = '#' + el.id;

        var itsType = getType(el);
        if(itsType == "text")
        {
            $j(elid).val('');
        }
        else if (itsType == "select")
        {
            $j(elid).val('');
        }
        else if (itsType == "checkbox")
        {
            $j(elid)[0].checked = '';
        }
        else if (itsType == "radio")
        {
            $j(elid)[0].checked = '';
        }
    }
};

C.ActiveAgent = Class.extend(
{
    init:function()
    {
        this.subscribers = {};
        this.actionList = {}; //action list based on event code
        this.oid = Math.random();

    },
    setup:function() {},
    svc : function(type, arg)
    {
        var retval = []
        var handler = this.actionList[type]; //array of Action
        if(handler)
        {
            for(var i = 0, ii = handler.length; i < ii; i++)
            {
                var actionObj = handler[i];
                if($j.isFunction(actionObj))
                {
                    var ret = actionObj.call(this, arg);
                    retval.push(ret);
                }
                else
                {
                    if(actionObj.canExecute(arg))
                    {
                        var ret = actionObj.impl.call(this, arg);
                        retval.push(ret);
                    }
                }
            }
        }
        return retval;
    },
    subscribe : function(type, listener)
    {
        if(!this.subscribers[type])
            this.subscribers[type] = [];
        this.subscribers[type].push(listener);
    },
    unsubscribe : function(type, listener)
    {
        if (this.subscribers[type] == 'undefined')
        {
            return;
        }
        var index = this.subscribers[type].indexOf(listener);
        if (this.subscribers[type][index])
        {
            this.subscribers[type].splice(index, 1);
        }
    },
    trigger : function(type, args)
    {
        if (this.subscribers[type])
        {
            args.oid = this.oid;
            var listeners = this.subscribers[type];
            for (var i = 0, ii = listeners.length; i < ii; i++)
            {
                if (typeof listeners[i] == 'function')
                {
                    listeners[i](args);
                }
                else if (typeof listeners[i] == 'object')
                {
                    if(typeof listeners[i].svc == "function")
                        listeners[i].svc.call(listeners[i], type, args);
                }
            }
        }
    },
    addAction:function(type, /*action instance*/action)
    {
        if(typeof this.actionList[type] == 'undefined')
            this.actionList[type] = [];
        this.actionList[type].push(action);
    },
    fini:function()
    {
        for(var item in this.actionList)
        {
            this.actionList[item] = null;
        }

        for(var item in this.subscribers)
        {
            this.subscribers[item] = null;
        }

        for(var item in this)
        {
            delete this[item];
        }
    },
    mapEventAction:function(target,evname, handler)
    {
        this.addAction(evname,handler);
        target.subscribe(evname,this);
    }
});


C.AjaxQueue = function()
{
    this.ajaxManager = $j.manageAjax.create(Math.random(),
    {
        queue: true,
        cacheResponse: true
    });
};

C.AjaxQueue.prototype =
{
    fini : function()
    {
        this.ajaxManager._unload();
        this.ajaxManager = null;
    },
    rpc:function(call)
    {
        if (!call.callback)
            throw new Error('Synchronous calls not supported.');

        var packet = JSON.stringify(call.request);
        var $this = this;
        this.ajaxManager.add(
        {
            type: "POST",
            url: call.url,
            data: {'':packet}, //workaround
            beforeSend: function(xhr) {
                xhr.setRequestHeader("X-JSON-RPC", call.request.method);
            },
            success: function(s) {
                    call.callback(JSON.eval(s));
            },
            error:function(x)
            {
                throw new Error(x);
            }
        });
    }
};

C.ajaxQueue = new C.AjaxQueue();

C.log = function(arg)
{
    window.console && window.console.log && window.console.log(arg);
}
